class Snake{
    head:HTMLElement;
    bodies:HTMLCollection;
    element:HTMLElement;
    constructor(){
        this.element=document.getElementById('snake')!;
        this.head=document.querySelector('#snake > div') as HTMLElement;
        this.bodies=this.element.getElementsByTagName('div');
        
    }
    get X(){
        return this.head.offsetLeft;
    }
    get Y(){
        return this.head.offsetTop;
    }
    //设置蛇头坐标
    set X(value:number){
        //如果新值和旧值相同，则直接返回不再修改
        if(this.X===value){
            return;
        }
        //X值的合法范围在0~290之间
        if(value<0 || value>290){
            throw new Error('蛇撞墙了！');            
        }
        //修改X时，就是修改在水平坐标，蛇在水平移动，蛇在向左移动时，不能向右掉头，反之亦然
        if(this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft===value){
            console.log("水平方向发生了掉头！");
            
            if(value>this.X){
                //如果新值value大于旧值X，则说明蛇在向右走，此时发生掉头，应该向左走
                value=this.X-10;
            }else{
                //向左走
                value=this.X+10;
            }
        }
        //移动蛇的身体
        this.moveBody();
        //移动蛇头
        this.head.style.left=value+'px';
        //检查有没有撞到自己
        this.checkHeadBody();
    }
    set Y(value:number){
        //如果新值和旧值相同，则直接返回不再修改
        if(this.Y===value){
            return;
        }
        //Y值的合法范围在0~290之间
        if(value<0 || value>290){
            throw new Error('蛇撞墙了！');            
        }
         //修改Y时，就是修改在纵向坐标，蛇在上下移动，蛇在向上移动时，不能向下掉头，反之亦然
         if(this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop===value){
            console.log("上下方向发生了掉头！");
            
            if(value>this.Y){
                //如果新值value大于旧值Y，则说明蛇在向上走，此时发生掉头，应该向下走
                value=this.Y-10;
            }else{
                value=this.Y+10;
            }
        }
        //移动蛇的身体
        this.moveBody();
        //移动蛇头
        this.head.style.top=value+'px';
        //检查有没有撞到自己
        this.checkHeadBody();
    }
    //蛇增加身体的方法
    addBody(){
        //向element中添加一个div
        this.element.insertAdjacentHTML('beforeend','<div></div>');
    }
    //移动蛇身体的方法
    moveBody(){
        //遍历获取所有的身体,不含蛇头，i=0的话是蛇头
        for(let i=this.bodies.length-1;i>0;i--){
            //获取前边身体的位置
            let X=(this.bodies[i-1] as HTMLElement).offsetLeft;
            let Y=(this.bodies[i-1] as HTMLElement).offsetTop;
            //将值设置到当前的身体上
            (this.bodies[i] as HTMLElement).style.left=X+'px';
            (this.bodies[i] as HTMLElement).style.top=Y+'px';
        }
    }
    //检查头部和身体有没有相撞
    checkHeadBody(){
        //获取所有的身体，检查其是否和蛇头的坐标发生重叠
        for(let i=1;i<this.bodies.length;i++){
            let bd=this.bodies[i] as HTMLElement;
            if(this.X===bd.offsetLeft && this.Y===bd.offsetTop){
                //进入判断，说明蛇头撞到了身体，游戏结束
                throw new Error ("撞到了自己！");
            }
        }
    }
}
export default Snake;